package com.only.fx;

import java.util.concurrent.CopyOnWriteArraySet;

import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Tooltip;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Screen;
import javafx.stage.Stage;

/**
 * @author XiaHui
 * @date 2017-10-27 11:07:28
 */
public class OnlyTitlePane extends HBox {

	private String only_title_pane_class = "only-title-pane";
	private String only_title_button_class = "only-title-button-pane";

	private BooleanProperty maximize = new SimpleBooleanProperty(false);
	private Rectangle2D backupWindowBounds = null;
	Stage stage;
	Scene scene;
	int style;
	OnlyMove move;
	boolean isAllowMaximized = true;

	StackPane minPane = new StackPane();
	StackPane maxPane = new StackPane();
	StackPane closePane = new StackPane();

	Button minButton = new Button();
	Button maxButton = new Button();
	Button closeButton = new Button();

	ImageView minImageView = new ImageView();
	ImageView maxImageView = new ImageView();
	ImageView closeImageView = new ImageView();

	Tooltip minTooltip = new Tooltip("最小化");
	Tooltip maxTooltip = new Tooltip("最大化");
	Tooltip restoreTooltip = new Tooltip("向下还原");
	Tooltip closeTooltip = new Tooltip("关闭");

	CopyOnWriteArraySet<EventHandler<ActionEvent>> closeActionSet = new CopyOnWriteArraySet<EventHandler<ActionEvent>>();
	CopyOnWriteArraySet<EventHandler<ActionEvent>> iconifiedActionSet = new CopyOnWriteArraySet<EventHandler<ActionEvent>>();

	VBox vBox=new VBox();
	HBox hBox=new HBox();
	
	HBox buttonBox=new HBox();
	
	public OnlyTitlePane(Stage stage, Scene scene, int style) {
		this.stage = stage;
		this.scene = scene;
		this.style = style;
		initPane();
		initEvent();
	}

	private void initPane() {
		move = new OnlyMove(stage, scene, this);
		this.setAlignment(Pos.TOP_RIGHT);
		// this.setBackground(Background.EMPTY);
		this.setPickOnBounds(false);// 面板不参与计算边界，透明区域无鼠标事件
		this.getStyleClass().add(only_title_pane_class);

		vBox.setPickOnBounds(false);// 面板不参与计算边界，透明区域无鼠标事件
		hBox.setPickOnBounds(false);// 面板不参与计算边界，透明区域无鼠标事件
		
		minButton.setFocusTraversable(false);
		minButton.getStyleClass().clear();
		minButton.getStyleClass().add("window-min");
		minButton.setGraphic(minImageView);
		minButton.setTooltip(minTooltip);

		maxButton.setFocusTraversable(false);
		maxButton.getStyleClass().clear();
		maxButton.getStyleClass().add("window-max");
		maxButton.setGraphic(maxImageView);
		maxButton.setTooltip(maxTooltip);

		closeButton.setFocusTraversable(false);
		closeButton.getStyleClass().clear();
		closeButton.getStyleClass().add("window-close");
		closeButton.setGraphic(closeImageView);
		closeButton.setTooltip(closeTooltip);

		minPane.getChildren().add(minButton);
		maxPane.getChildren().add(maxButton);
		closePane.getChildren().add(closeButton);

		minPane.getStyleClass().add(only_title_button_class);
		maxPane.getStyleClass().add(only_title_button_class);
		closePane.getStyleClass().add(only_title_button_class);
		
		
		buttonBox.setAlignment(Pos.TOP_RIGHT);
		
		HBox tempBox=new HBox();
		
		tempBox.getChildren().add(buttonBox);
		tempBox.getChildren().add(hBox);
		
		vBox.getChildren().add(tempBox);
		this.getChildren().add(vBox);
	}

	private void initEvent() {

		this.maximizeProperty().addListener(new ChangeListener<Boolean>() {

			@Override
			public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
				toogleMaximized();
			}
		});

		closeButton.setOnAction((ActionEvent actionEvent) -> {
			if (!closeActionSet.isEmpty()) {
				for (EventHandler<ActionEvent> e : closeActionSet) {
					e.handle(actionEvent);
				}
			} else {
				stage.close();
			}
		});

		minButton.setOnAction((ActionEvent actionEvent) -> {
			if (!iconifiedActionSet.isEmpty()) {
				for (EventHandler<ActionEvent> e : iconifiedActionSet) {
					e.handle(actionEvent);
				}
			} else {
				stage.setIconified(true);
			}
		});

		maxButton.setOnAction((ActionEvent actionEvent) -> {
			doMaximize();
		});
		setTitlePaneStyle(style);
	}

	public final BooleanProperty maximizeProperty() {
		return this.maximize;
	}

	public void setMaximize(boolean maximize) {
		this.maximizeProperty().set(maximize);
	}

	public boolean isMaximize() {
		return this.maximizeProperty().get();
	}

	public void doMaximize() {
		if (isAllowMaximized) {
			boolean max = isMaximize();
			setMaximize(!max);
		}
	}

	private void toogleMaximized() {
		ObservableList<Screen> list = Screen.getScreensForRectangle(stage.getX(), stage.getY(), 1, 1);

		if (null != list && !list.isEmpty()) {
			final Screen screen = list.get(0);
			if (isMaximize()) {
				backupWindowBounds = new Rectangle2D(stage.getX(), stage.getY(), stage.getWidth(), stage.getHeight());
				stage.setX(screen.getVisualBounds().getMinX());
				stage.setY(screen.getVisualBounds().getMinY());
				stage.setWidth(screen.getVisualBounds().getWidth());
				stage.setHeight(screen.getVisualBounds().getHeight());

				maxButton.getStyleClass().clear();
				maxButton.getStyleClass().add("window-restore");
				maxButton.setTooltip(restoreTooltip);
			} else {
				if (backupWindowBounds != null) {
					stage.setX(backupWindowBounds.getMinX());
					stage.setY(backupWindowBounds.getMinY());
					stage.setWidth(backupWindowBounds.getWidth());
					stage.setHeight(backupWindowBounds.getHeight());
				}
				maxButton.getStyleClass().clear();
				maxButton.getStyleClass().add("window-max");
				maxButton.setTooltip(maxTooltip);
			}
		}
	}

	public void setTitlePaneStyle(int style) {
		// double width = 0;
		// double height = 27;
		hBox.getChildren().remove(minPane);
		hBox.getChildren().remove(maxPane);
		hBox.getChildren().remove(closePane);
		if (style == 1) {
			hBox.getChildren().addAll(minPane, maxPane, closePane);
			// width = minButton.getWidth() + maxButton.getWidth() +
			// closeButton.getWidth();
		} else if (style == 2) {
			hBox.getChildren().addAll(minPane, closePane);
			// width = minButton.getWidth() + closeButton.getWidth();
			isAllowMaximized = false;
		} else if (style == 3) {
			hBox.getChildren().addAll(closePane);
			// width = closeButton.getWidth();
			isAllowMaximized = false;
		} else {
			hBox.getChildren().addAll(minPane, maxPane, closePane);
			// width = minButton.getWidth() + maxButton.getWidth() +
			// closeButton.getWidth();
		}
	}

	public void addOnCloseAction(EventHandler<ActionEvent> e) {
		closeActionSet.add(e);
	}

	public void addIconifiedAction(EventHandler<ActionEvent> e) {
		iconifiedActionSet.add(e);
	}

	public void setMinButtonImage() {

	}

	public void setMaxButtonImage() {

	}

	public void setRestoreButtonImage() {

	}

	public void setCloseButtonImage() {

	}
}
